package com.lgCore.server;

import com.lgCore.rpc.common.codec.RpcProtobufDecoder;
import com.lgCore.rpc.common.codec.RpcProtobufEncoder;
import com.lgCore.serverHandler.RpcHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.net.InetSocketAddress;

@Data
@Slf4j
@Service("ChatServer")
public class ChatServer {
    // 服务器端口
//    @Value("${server.port}")
    private int port = 9986;
    // 通过nio方式来接收连接和处理连接
    private EventLoopGroup bg =
            new NioEventLoopGroup();
    private EventLoopGroup wg =
            new NioEventLoopGroup();

    // 启动引导器
    private ServerBootstrap b =
            new ServerBootstrap();


    public void run() {
        //1 设置reactor 线程
        b.group(bg, wg);
        //2 设置nio类型的channel
        b.channel(NioServerSocketChannel.class);
        //3 设置监听端口
//        String ip = IOUtil.getHostAddress();
        b.localAddress(new InetSocketAddress("192.168.20.149", port));
        //4 设置通道选项
        b.option(ChannelOption.SO_BACKLOG, 128);
        b.option(ChannelOption.SO_KEEPALIVE, true);
        //通过NoDelay禁用Nagle,使消息立即发出去，不用等待到一定的数据量才发出去
        b.option(ChannelOption.TCP_NODELAY, true);
//        b.option(ChannelOption.ALLOCATOR,
//                PooledByteBufAllocator.DEFAULT);

        //5 装配流水线
        b.childHandler(new ChannelInitializer<SocketChannel>() {
            //有连接到达时会创建一个channel
            protected void initChannel(SocketChannel ch) throws Exception {
                // 管理pipeline中的Handler
                ch.pipeline().addLast("deCoder", new RpcProtobufDecoder());
                ch.pipeline().addLast("enCoder", new RpcProtobufEncoder());
//                ch.pipeline().addLast("heartBeat", new HeartBeatServerHandler());
                // 在流水线中添加handler来处理登录,登录后删除
//                ch.pipeline().addLast("loginRequest",loginRequestHandler);
//                ch.pipeline().addLast("remoteNotificationHandler",remoteNotificationHandler);
                ch.pipeline().addLast("chatRedirect", new RpcHandler());
//                ch.pipeline().addLast("serverException",serverExceptionHandler);
            }
        });

        ChannelFuture f= null;
        try {
            f = b.bind(port).sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if(f.isSuccess()){
            System.out.println("-------------rpc server start---------------");
        }


//        // 6 开始绑定server
//        // 通过调用sync同步方法阻塞直到绑定成功
//
//        ChannelFuture channelFuture = null;
//        boolean isStart = false;
//        while (!isStart) {
//            try {
//
//                channelFuture = b.bind().sync();
//                log.info("疯狂创客圈 CrazyIM 启动, 端口为： " +
//                        channelFuture.channel().localAddress());
//                isStart = true;
//            } catch (Exception e) {
//                log.error("发生启动异常", e);
//                port++;
//                log.info("尝试一个新的端口：" + port);
//                b.localAddress(new InetSocketAddress(port));
//            }
//        }
//        try {
//            // 7 监听通道关闭事件
//            // 应用程序会一直等待，直到channel关闭
//            ChannelFuture closeFuture =
//                    channelFuture.channel().closeFuture();
//            closeFuture.sync();
//        } catch (
//                Exception e) {
//            log.error("发生其他异常", e);
//        } finally {
//            // 8 优雅关闭EventLoopGroup，
//            // 释放掉所有资源包括创建的线程
//            wg.shutdownGracefully();
//            bg.shutdownGracefully();
//        }

    }


    public static void main(String[] args) {
        new ChatServer().run();
    }
}
